﻿using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Game.model;
using ikvm.extensions;
using java.io;
using java.lang;
using java.util;
using java.util.concurrent;
using lineage2.commons.threading;
using org.apache.commons.io;
using org.slf4j;
using ArrayList = java.util.ArrayList;
using Exception = System.Exception;
using String = System.String;

namespace Game
{
    public class Announcements
    {
        public class Announce:RunnableImpl
        {
            private Future _task;
		    /**
		     * Field _time.
		     */
		    private int _time;
		    /**
		     * Field _announce.
		     */
		    private String _announce;
            public Announce(int t, String announce)
		    {
			    _time = t;
			    _announce = announce;
		    }
		
		    /**
		     * Method runImpl.
		     */
		    
		    public override void runImpl()
		    {
			    announceToAll(_announce);
		    }
            public void showAnnounce(Player player)
            {
                Say2 cs = new Say2(0, ChatType.ANNOUNCEMENT, player.getName(), _announce);
                player.sendPacket(cs);
            }
            public void start()
            {
                if (_time > 0)
                {
                    _task = ThreadPoolManager.getInstance().scheduleAtFixedRate(this, _time * 1000L, _time * 1000L);
                }
            }
            public void stop()
            {
                if (_task != null)
                {
                    _task.cancel(false);
                    _task = null;
                }
            }
            public int getTime()
            {
                return _time;
            }
            public String getAnnounce()
            {
                return _announce;
            }
        }
        private static Logger _log = LoggerFactory.getLogger(typeof(Announcements));
	/**
	 * Field _instance.
	 */
	    private static Announcements _instance = new Announcements();
        public static Announcements getInstance()
	    {
		    return _instance;
	    }
	    private List _announcements = new ArrayList();
	    private Announcements()
	    {
		    loadAnnouncements();
	    }
        public List getAnnouncements()
        {
            return _announcements;
        }
        public void loadAnnouncements()
	    {
		    _announcements.clear();
		    try
		    {
			    List lines = Arrays.asList(FileUtils.readFileToString(new File("config/announcements.txt"), "UTF-8").split("\n"));
			    foreach (String line in (IEnumerable)lines)
			    {
				    StringTokenizer token = new StringTokenizer(line, "\t");
				    if (token.countTokens() > 1)
				    {
					    addAnnouncement(Integer.parseInt(token.nextToken()), token.nextToken(), false);
				    }
				    else
				    {
					    addAnnouncement(0, line, false);
				    }
			    }
		    }
		    catch (Exception e)
		    {
			    _log.error("Error while loading config/announcements.txt!");
		    }
	    }
        public void showAnnouncements(Player activeChar)
	    {
		    foreach (Announce announce in (IEnumerable)_announcements)
		    {
			    announce.showAnnounce(activeChar);
		    }
	    }
        public void addAnnouncement(int val, String text, bool save)
        {
            Announce announce = new Announce(val, text);
            announce.start();
            _announcements.add(announce);
            if (save)
            {
                saveToDisk();
            }
        }
        public void delAnnouncement(int line)
        {
            Announce announce = _announcements.remove(line) as Announce;
            if (announce != null)
            {
                announce.stop();
            }
            saveToDisk();
        }
        private void saveToDisk()
	    {
		    try
		    {
			    var f = new File("config/announcements.txt");
			    var writer = new FileWriter(f, false);
			    foreach (Announce announce in (IEnumerable)_announcements)
			    {
				    writer.write(announce.getTime() + "\t" + announce.getAnnounce() + "\n");
			    }
			    writer.close();
		    }
		    catch (Exception e)
		    {
			    _log.error("Error while saving config/announcements.txt!", e);
		    }
	    }
        public void announceToAll(String text)
        {
            announceToAll(text, ChatType.ANNOUNCEMENT);
        }
        public static void shout(Creature activeChar, String text, ChatType type)
	    {
		    Say2 cs = new Say2(activeChar.getObjectId(), type, activeChar.getName(), text);
		    int rx = MapUtils.regionX(activeChar);
		    int ry = MapUtils.regionY(activeChar);
		    int offset = Config.SHOUT_OFFSET;
		    foreach (Player player in GameObjectsStorage.getAllPlayersForIterate())
		    {
			    if ((player == activeChar) || (activeChar.getReflection() != player.getReflection()))
			    {
				    continue;
			    }
			    int tx = MapUtils.regionX(player);
			    int ty = MapUtils.regionY(player);
			    if (((tx >= (rx - offset)) && (tx <= (rx + offset)) && (ty >= (ry - offset)) && (ty <= (ry + offset))) || activeChar.isInRangeZ(player, Config.CHAT_RANGE))
			    {
				    player.sendPacket(cs);
			    }
		    }
		    activeChar.sendPacket(cs);
	    }
        public void announceToAll(String text, ChatType type)
	    {
		    Say2 cs = new Say2(0, type, "", text);
		    foreach (Player player in GameObjectsStorage.getAllPlayersForIterate())
		    {
			    player.sendPacket(cs);
		    }
	    }
        public void announceToAll(IStaticPacket sm) 
        {
			foreach(Player player in GameObjectsStorage.getAllPlayersForIterate())
				player.sendPacket(sm);
        }
        public void announceByCustomMessage(String address, String[] replacements)
	    {
		    foreach (Player player in GameObjectsStorage.getAllPlayersForIterate())
		    {
			    announceToPlayerByCustomMessage(player, address, replacements);
		    }
	    }
        public void announceByCustomMessage(String address, String[] replacements, ChatType type)
	    {
		    foreach (Player player in GameObjectsStorage.getAllPlayersForIterate())
		    {
			    announceToPlayerByCustomMessage(player, address, replacements, type);
		    }
	    }
        public void announceToPlayerByCustomMessage(Player player, String address, String[] replacements)
	    {
		    CustomMessage cm = new CustomMessage(address, player);
		    if (replacements != null)
		    {
			    foreach (String s in replacements)
			    {
				    cm.addString(s);
			    }
		    }
		    player.sendPacket(new Say2(0, ChatType.ANNOUNCEMENT, "", cm.toString()));
	    }
        public void announceToPlayerByCustomMessage(Player player, String address, String[] replacements, ChatType type)
	    {
		    CustomMessage cm = new CustomMessage(address, player);
		    if (replacements != null)
		    {
			    foreach (String s in replacements)
			    {
				    cm.addString(s);
			    }
		    }
		    player.sendPacket(new Say2(0, type, "", cm.toString()));
	    }
        public void announceToAll(SystemMessage sm)
	    {
		    foreach (Player player in GameObjectsStorage.getAllPlayersForIterate())
		    {
			    player.sendPacket(sm);
		    }
	    }
    }
}
